package ace.module.product.core.impl.manager.impl;

import ace.cmp.core.constants.CoreConstant;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveContext;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveListContext;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.utils.SaveContextUtils;
import ace.cmp.util.AceAssertUtils;
import ace.module.common.core.impl.manager.impl.AbstractEntityOfAppManager;
import ace.module.product.api.model.dto.PmsProductSkuAttributeValueDto;
import ace.module.product.api.model.input.PmsProductSkuSaveInput;
import ace.module.product.core.impl.dao.entity.PmsProductAttribute;
import ace.module.product.core.impl.dao.entity.PmsProductAttributeValue;
import ace.module.product.core.impl.dao.entity.PmsProductSku;
import ace.module.product.core.impl.dao.entity.PmsProductSkuAttributeValue;
import ace.module.product.core.impl.dao.repository.PmsProductSkuAttributeValueRepository;
import ace.module.product.core.impl.manager.PmsProductSkuAttributeValueManager;
import ace.module.product.core.impl.manager.helper.PmsProductAttributeHelperMgr;
import ace.module.product.core.impl.manager.helper.PmsProductAttributeValueHelperMgr;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 商品Sku的规格属性值 spring data jdbc querydsl rsql manager implement.
 *
 * @author Caspar
 */
@Slf4j
@AllArgsConstructor
@Component
public class PmsProductSkuAttributeValueManagerImpl
    extends AbstractEntityOfAppManager<PmsProductSkuAttributeValue, Long, PmsProductSkuAttributeValueDto>
    implements PmsProductSkuAttributeValueManager {

  private final PmsProductAttributeHelperMgr pmsProductAttributeHelperMgr;
  private final PmsProductAttributeValueHelperMgr pmsProductSkuAttributeValueBizMgr;
  private final PmsProductSkuAttributeValueRepository pmsProductSkuAttributeValueRepository;

  @Override
  public SaveListContext<PmsProductSkuAttributeValue> assemblePmsProductSkuAttributeValueSaveListContext(
      SaveContext<PmsProductSku> pmsProductSkuSaveContext,
      SaveListContext<PmsProductAttribute> pmsProductAttributeSaveListContext,
      SaveListContext<PmsProductAttributeValue> pmsProductAttributeValueSaveListContext,
      PmsProductSkuSaveInput pmsProductSkuSaveInput) {

    List<String> keys = pmsProductSkuSaveInput.getAttributes().keySet().stream().collect(Collectors.toList());

    List<SaveContext<PmsProductSkuAttributeValue>> pmsProductSkuAttributeValueSaveContexts = LongStream.range(0, keys.size())
        .mapToObj(index -> {
          String name = keys.get((int) index);
          String value = pmsProductSkuSaveInput.getAttributes().get(name);
          return this.assemblePmsProductSkuAttributeValueSaveContext(
              pmsProductSkuSaveContext,
              pmsProductAttributeSaveListContext,
              pmsProductAttributeValueSaveListContext,
              name,
              value,
              index
          );
        })
        .collect(Collectors.toList());

    AceAssertUtils.isEmpty(pmsProductSkuAttributeValueSaveContexts, "商品sku属性不能为空");

    return SaveContextUtils.of(pmsProductSkuAttributeValueSaveContexts);
  }

  private SaveContext<PmsProductSkuAttributeValue> assemblePmsProductSkuAttributeValueSaveContext(
      SaveContext<PmsProductSku> pmsProductSkuSaveContext,
      SaveListContext<PmsProductAttribute> pmsProductAttributeSaveListContext,
      SaveListContext<PmsProductAttributeValue> pmsProductAttributeValueSaveListContext,
      String productSkuAttributeName,
      String productSkuAttributeValue,
      Long sort
  ) {
    List<PmsProductAttribute> pmsProductAttributes = pmsProductAttributeSaveListContext.getNewOrModifyOriginData();
    AceAssertUtils.isEmpty(productSkuAttributeName, "保存商品sku属性失败,商品规格属性名不能为空");
    Optional<PmsProductAttribute> productAttributeOptional = this.pmsProductAttributeHelperMgr.findByName(pmsProductAttributes, productSkuAttributeName);
    AceAssertUtils.isTrue(productAttributeOptional.isEmpty(), "保存商品sku属性失败,[%s]关联商品规格属性失败", productSkuAttributeName);

    List<PmsProductAttributeValue> pmsProductAttributeValues = pmsProductAttributeValueSaveListContext.getNewOrModifyOriginData();
    AceAssertUtils.isEmpty(productSkuAttributeValue, "保存商品sku属性失败,商品规格属性值不能为空");
    Optional<PmsProductAttributeValue> productAttributeValueOptional = this.pmsProductSkuAttributeValueBizMgr.findByValue(pmsProductAttributeValues, productSkuAttributeValue);
    AceAssertUtils.isTrue(productAttributeValueOptional.isEmpty(), "保存商品sku属性值失败,[%s]关联商品规格属性值失败", productSkuAttributeValue);

    PmsProductSku pmsProductSku = pmsProductSkuSaveContext.getData();
    PmsProductSkuAttributeValue pmsProductSkuAttributeValue = null;
    if (pmsProductSkuSaveContext.isModify()) {
      pmsProductSkuAttributeValue = this.pmsProductSkuAttributeValueRepository.findByPmsAppIdAndProductIdAndProductSkuIdAndNameAndValueAndDeleteFlag(
          pmsProductSku.getPmsAppId(),
          pmsProductSku.getProductId(),
          pmsProductSku.getId(),
          productSkuAttributeName,
          productSkuAttributeValue,
          CoreConstant.DELETE_FLAG_NOT
      );
    }
    boolean isAdd = Objects.isNull(pmsProductSkuAttributeValue);
    if (isAdd) {
      pmsProductSkuAttributeValue = PmsProductSkuAttributeValue.builder()
          .id(this.getNewId())
          .pmsAppId(pmsProductSku.getPmsAppId())
          .shopId(pmsProductSku.getShopId())
          .productId(pmsProductSku.getProductId())
          .productSkuId(pmsProductSku.getId())
          .build();
    }
    pmsProductSkuAttributeValue.setName(productSkuAttributeName);
    pmsProductSkuAttributeValue.setValue(productSkuAttributeValue);
    pmsProductSkuAttributeValue.setSort(sort);
    return SaveContextUtils.of(pmsProductSkuAttributeValue, isAdd);
  }
}
